#!/usr/bin/perl -w
use strict;
use Getopt::Std;

######################################################
#gestion des options
######################################################
my %opts;
getopts("vhi:o:", \%opts) || &usage;

#si option -h : appel sub usage indiquant l'utilisation du programme
if(defined($opts{h}))
	{
	&usage;
	}

#######################################################
#affichage des messages de testptq	
#######################################################
my $prompt = "PTQ.TEST:>";

#######################################################
#fichiers utilises par le programme
#######################################################
my $refout = "refout";
my $testin;
my $testout;	
my $testdiff = "testdiff";

if(defined($opts{i})){$testin = $opts{i};}	#on peut chosir l'input
else {$testin = "testin";}	#input par defaut : testin

if(defined($opts{o})){$testout = $opts{o};}	#on peut chosir l'output
else {$testout = "testout";}	#output par defaut : testout

###########################################################################
#lancement de ptq sur l'input testin et ecriture des resultats dans testout
###########################################################################
open(INPUT, "$testin") || die "open error on INPUT open (reading)\n";
open(OUTPUT, ">$testout") || die "open error on OUTPUT open (writing)\n";

print"\n\n";
print "=================================\n";
print "$prompt Lancement de PTQ...\n";
print OUTPUT `./ptq -d3 -t ./data/testtds < $testin`;
#PTQ avec trace = 3 : erreurs verbeuses, correspondance claire avec input
#PTQ avec tds vide 
print "$prompt ... Fin PTQ\n";
print "=================================\n";

close (OUTPUT);
close(INPUT);

###########################################################################
#lancement de diff sur le repere refout et testout, ecriture dans testdiff
###########################################################################
&diff($testdiff,$refout,$testout);

###########################################################################
#evaluation du diff : quantification des differences et erreurs
###########################################################################
my @eval = &evaluation($testdiff);

###########################################################################
#affichage des resultats du test : quantification
###########################################################################
&affiche_test(@eval);	

###########################################################################
#si option -v specifiee : 
#appel de la sub verbose_evaluation qui indique les erreurs
###########################################################################
if(defined($opts{v}))
	{&verbose_evaluation($testout);}	#reperage des erreurs


###########################################################################
#SUBS (diff, evaluation, affiche_test, verbose_evaluation, usage
###########################################################################
sub diff
	{
	open(DIFF, ">$_[0]") || die "error on DIFF open (writing)\n";
	print DIFF `diff -y --suppress-common-lines $_[1] $_[2]`;
	close(DIFF);
	}

sub evaluation
	{
	open(EVAL, "$_[0]") || die "error on EVAL open (reading)\n";
	my $nblignes = 0;
	my $differences = 0;
	my $erreurs = 0;
	while(<EVAL>)
		{
		$nblignes++;
		if($_ =~ /Erreur/){$erreurs++;}
		if($_ =~ /\|\s*PTQ:>/) {$differences++}
		}
	my @eval = ($nblignes, $differences, $erreurs);
	close(EVAL);
	return @eval;
	}

sub affiche_test
	{
	print "\n\n";
	printf "%50s", "======================TEST========================\n";
	printf "%15s", "lignes divergentes";
	printf "%15s", "differences";
	printf "%15s", "erreurs";
	print "\n";
	printf "%15d", "$_[0]";
	printf "%15d", "$_[1]";
	printf "%15d", "$_[2]";
	print "\n";
	printf "%50s", "==================================================\n";
	print "\n\n";	
	}

sub verbose_evaluation	
	{
	print "================================ERREURS==================================\n";
	my $erreurno = 1;
	open(VEVAL, "$_[0]") || die "error on VEVAL open (reading)\n";	
	while(<VEVAL>)
		{
		if($_ =~ /Erreur.+?([0-9]+).+?(".+?").+?(".+?")/)
			{
			my $line = $1; my $text = $2; my $token = $3;
			printf "Erreur $erreurno == ${testin}::ligne$line $text a la position $token\n";
			$erreurno++;
			#!! si affichage console : les lignes peuvent etre ecrasees
			#dans ce cas faire une redirection dans un fichier texte
			}
		}
	printf "=========================================================================\n";
	print "\n\n";	
	close(VEVAL);
	}


sub usage
	{
	print "\n\n\t========USAGE=======\n";
	print "\t./testptq.pl [-v] [-h] [-i fichier] [-o fichier]\n";
	print "\tno options => affichage statistique : differences/erreurs entre output et output repere\n";
	print "\t[-v] => test verbeux : affiche egalement les erreurs trouvees de facon explicite\n";
	print "\t[-h] => affiche ce message\n";
	print "\t[-i fichier] => specification de l'input pour PTQ\n";
	print "\t(par defaut le test est lance sur <testin>)\n";
	print "\t[-o fichier] => specification de l'output pour PTQ\n";
	print "\t(par defaut le test ecrit le resultat de PTQ dans <testout>)\n";
	print "\tl'output est toujours compare a <refout> produit par <refin>\n";
	print "\n\n";
	exit;
	}
